<template>
  <a-spin :spinning="confirmLoading" style="background: #fff">
    <j-form-container :disabled="false">
      <a-form-model ref="form" :model="model" slot="detail">
        <a-collapse v-model="activeKey">
          <a-collapse-panel key="1" header="项目信息">
            <a-row :gutter="48">
              <a-col :span="8">
                <a-form-model-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="billNo">
                  <!-- 为了避免冲突，这里将j-input的disabled改成属性isDisabled -->
                  <j-input v-model="model.billNo" placeholder="请输入单据编号" :isDisabled="true"></j-input>
                </a-form-model-item>
              </a-col>
              <a-col :span="8">
                <a-form-model-item label="填报时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="fillInTime">
                  <j-date
                    placeholder="请选择填报时间"
                    v-model="model.fillInTime"
                    :show-time="true"
                    date-format="YYYY-MM-DD HH:mm:ss"
                    style="width: 100%"
                    disabled
                  />
                </a-form-model-item>
              </a-col>
              <a-col :span="8">
                <a-form-model-item label="填报人" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="fillInUser">
                  <!-- <select-user-by-dep :multi="false" v-model="model.handlerId" disabled /> -->
                  <j-select-user-by-dep v-model="model.fillInUser" :multi="false" disabled></j-select-user-by-dep>
                </a-form-model-item>
              </a-col>
              <a-col :span="8">
                <a-form-model-item label="所属部门" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="handlerDeptId">
                  <!-- <j-select-depart v-model="model.handlerDeptId" disabled/> -->
                  <j-select-depart
                    v-model="model.handlerDeptId"
                    :trigger-change="true"
                    disabled
                    :multi="true"
                  ></j-select-depart>
                </a-form-model-item>
              </a-col>
              <!-- <a-col :span="16">
                <a-form-model-item label="生产日期"  :wrapperCol="wrapperCol" prop="workingHours">
                  <a-range-picker :placeholder="['请选择填报时间', '请选择填报时间']" v-model="workingHours" disabled>
                  </a-range-picker>
                </a-form-model-item>
              </a-col> -->
            </a-row>
          </a-collapse-panel>
          <a-collapse-panel key="2" header="填报日期">
            <a-space>
              <!-- 工时选择 -->
              <div class="date-area" v-for="(it,index) in lastWeekWorkingHours" :key="index"
                :class="it.isClick?'bg1':''" @click="clickWorkingHours(it)">
                <img class="left-icon" v-if="it.alearyFillButUnStatic==='no'" src="@assets/unFinished.png" alt="">
                <img class="left-icon" v-else src="@assets/finished.png" alt="">
                <span class="date">{{it.nowDate}}</span>
                <span class="week">{{it.nowWeek}}</span>
              </div>
            </a-space>
          </a-collapse-panel>
          <a-collapse-panel key="3">
            <!-- 自定义标题 -->
            <template slot="header">
              <span>任务信息</span>
              <span class="ipt-task-time-header-right" v-if="status==='add'">
                {{ contentTitle }}: {{ sum }}（小时），剩余可填工时：{{ remain }}（小时）
              </span>
              <span class="ipt-task-time-header-right" v-else-if="status==='fillLastWeek'">
                {{ contentTitle }}: {{ sum }}（小时），剩余可补填工时：{{ remain }}（小时）
              </span>
              <!-- 查看今日 -->
              <span class="ipt-task-time-header-right" v-else-if="status==='viewThisWeek'||status==='viewLastWeek'||status==='pierce'">
                {{ contentTitle }}: {{ sum }}（小时）
              </span>
            </template>
            <a-table
              ref="table"
              size="middle"
              :scroll="{ x: scrollX }"
              :components="draggableComponent"
              bordered
              rowKey="projectTaskId"
              :columns="columns"
              :dataSource="dataSource"
              :loading="loading"
              class="j-table-force-nowrap"
            >
              <template slot="projectName" slot-scope="text, record">
                <p @click="clickProjectName(record)" style="color: #00aaf0; cursor: pointer;white-space: pre-wrap;"><span>{{ text }}</span></p>
              </template>
              <template slot="fillHours" slot-scope="text, record">
                <a-input-number
                  :disabled="!initStatus.canEdit"
                  :min="0"
                  :max="8"
                  :step="0.1"
                  v-model="record.fillHours"
                  :precision="1"
                  @change="changeFillHours(record)"
                >
                </a-input-number>
              </template>
            </a-table>
            <a-button v-if="status==='fillLastWeek'" class="fl-right" type="primary"
              @click="saveTo">保存</a-button>
          </a-collapse-panel>

          <a-collapse-panel header="流程历史跟踪" key="3" v-if="initStatus.showHistoryTrack">
            <a-table
              ref="table"
              size="middle"
              :scroll="{ x: scrollX }"
              :components="draggableComponent"
              bordered
              rowKey="id"
              :columns="historyTrackColumns"
              :dataSource="historyTrackDataSource"
              :loading="historyTrackLoading"
              class="j-table-force-nowrap"
            >
            </a-table>
          </a-collapse-panel>
        </a-collapse>
      </a-form-model>
    </j-form-container>
    <erp-project-report-modal ref="viewProjectDetail" @ok="modalFormOk"></erp-project-report-modal>

  </a-spin>
</template>
<script>
import moment from 'moment'
import { mapGetters } from 'vuex'
// 获取单据编号
import { generatedFormNumber } from '@/utils/getBillNo'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Decimal from 'decimal.js'
import { postAction, getAction, putAction } from '@/api/manage'
import ErpProjectReportModal from '@/views/erp/report/project/modules/ErpProjectReportModal'

export default {
  components: {ErpProjectReportModal},
  mixins: [JeecgListMixin],
  data() {
    return {
      disableMixinCreated:true,
      // 表头
      columns:  [
        {
          title: '序号',
          dataIndex: '',
          key: 'rowIndex',
          width: 60,
          align: 'center',
          ellipsis: true,
          customRender: function (t, r, index) {
            return parseInt(index) + 1
          },
        },
        {
          title: '项目名称',
          align: 'center',
          dataIndex: 'projectName',
          width: 600,
          // ellipsis: true,
          scopedSlots: {
            customRender: 'projectName',
          },
        },{
          title: '项目类型',
          align: 'center',
          dataIndex: 'isRdTask_dictText',
          width: 100,
          ellipsis: true,
        },
        {
          title: '项目档案编号',
          align: 'center',
          dataIndex: 'projectNo',
          width: 300,
          ellipsis: true,
        },
        {
          title: '业务分类',
          align: 'center',
          dataIndex: 'categoryName',
          width: 200,
          ellipsis: true,
        },
        {
          title: '任务档案编号',
          align: 'center',
          dataIndex: 'taskNo',
          width: 300,
          ellipsis: true,
        },
        {
          title: '已填报工时（小时）',
          align: 'center',
          dataIndex: 'lastFillHours',
          width: 200,
          ellipsis: true,
        },
        {
          title: '今日投入工时（小时）',
          align: 'center',
          dataIndex: 'fillHours',
          width: 200,
          ellipsis: true,
          scopedSlots: {
            customRender: 'fillHours',
          },
          fixed: 'right',
        },
      ],
      historyTrackColumns: [
        {
          title: '序号',
          dataIndex: '',
          key: 'rowIndex',
          width: 60,
          align: 'center',
          ellipsis: true,
          customRender: function (t, r, index) {
            return parseInt(index) + 1
          },
        },
        {
          title: '名称',
          align: 'center',
          dataIndex: 'name',
          width: 400,
          ellipsis: true,
        },
        {
          title: '开始时间',
          align: 'center',
          dataIndex: 'startTime',
          width: 132,
          ellipsis: true,
        },
        {
          title: '结束时间',
          align: 'center',
          dataIndex: 'endTime',
          width: 132,
          ellipsis: true,
        },
        {
          title: '负责人',
          align: 'center',
          dataIndex: 'leaderId_dictText',
          width: 132,
          ellipsis: true,
        },
        {
          title: '处理结果',
          align: 'center',
          dataIndex: 'status',
          width: 132,
          ellipsis: true,
        },
        {
          title: '处理意见',
          align: 'center',
          dataIndex: 'remark',
          width: 132,
          ellipsis: true,
        },
      ],
      historyTrackDataSource: [],
      historyTrackLoading: false,
      confirmLoading: false,
      model: {},
      activeKey: ['1', '2', '3'],
      labelCol: {},
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 24 },
      },
      workingHours: [],
      url: {
        list: '',
        getBillNo: '',
        submitData: '',
        getFormData: '',
        getHistoryTrack: '',
        // 项目一览表
        queryProjectById: '/api/erp/project/report/erpProjectReport/queryById',
        queryHisWorkingHours: '/api/erp/hours/workmain/erpWorkingHours/queryDayHistoryWorkingHours',//查询历史工时
        allSubmitUrl: '/api/erp/hours/workmain/erpWorkingHours/missAllSubmit', //补填时全部提交
      },
      dataSource: [],
      mostImportantParams: {
        // 这里的这个isInspection需要修改，改成只有今日未填报的时候设置
        pageSize: -1,
      },
      total: 8,
      // 每次新打开弹框的时候数据是都更新了的，因为请求接口，但是自定义的状态并不会更新，所以需要手动设置
      // 即使类似modal设置了destroyOnClose，也只会销毁内部元素，并不会改变状态
      // 如果要更新的状态特别多，考虑封装的话，可以把状态包裹起来，然后在simpleDrawer关闭的时候去$emit一个事件，父组件去监听这个事件，然后去重置inputTaskTime的状态

      // 现在通过将自定义的状态都放到initStatus里面，每次重新打开弹框，都会触发status的watch，从而调用resetInitStatus()，重置initStatus的状态
      initStatus: {
        canEdit: false, // 是否可编辑
        showHistoryTrack: false, // 是否显示流程历史轨迹,
        // 主表查询参数
        formDataParams: {},
      },
      controlLoadData: false,
      lastWeekWorkingHours: [],//以前投入的工时列表
      nowClickParams: {},//当前点击item数据
    }
  },
  props: {
    status: {
      type: String,
      default: 'add',
      required: false,
    },
    contentTitle: {
      type: String,
      default: '',
      required: false,
    },
    list: {
      type: String,
      default: '',
      required: false,
    },
    urlSubmitData: {
      type: String,
      default: '',
      required: false,
    },
    urlGetFormData: {
      type: String,
      default: '',
      required: false,
    },
    urlGetHistoryTrack: {
      type: String,
      default: '',
      required: false,
    },
    pierceBillNo: {
      type: String,
      default: '',
      required: false,
    },
    userType: {
      type: String,
      default: ''
    },
    formDataParams: {
      type: Object,
      default: () => {},
      required: false
    }
  },
  watch: {
    status: {
      async handler(val) {
        // 每次进入页面的时候都先重置状态，再根据status去设置状态
        this.resetInitStatus()
        this.url.list = this.list && this.list
        this.url.submitData = this.urlSubmitData && this.urlSubmitData
        this.url.getFormData = this.urlGetFormData && this.urlGetFormData
        this.url.getHistoryTrack = this.urlGetHistoryTrack && this.urlGetHistoryTrack
        switch (val) {
          // 如果是新增页面，才有必要初始化数据
          case 'add':
            this.lastWeekWorkingHours = [{
              alearyFillButUnStatic: 'no',
              isClick: true,
              nowDate: moment().format('MMMDD日'), //当前日期
              nowWeek: moment().format('dddd') //当前星期
            }]
            this.controlLoadData = true
            // 只有今日未填报时才有
            this.mostImportantParams.isInspection = 'no'
            await this.loadData()
            this.dataSource.forEach((item) => {
              item.fillHours = 0.0
            })
            await this.setInitData()
            // 设置表格可输入状态
            this.initStatus.canEdit = true
            break
          case 'pierce':
            this.initStatus.showHistoryTrack = true
            this.activeKey = ['1', '2', '3']
            this.controlLoadData = true
            // 单据编号穿透特有的初始化
            await this.setPierceInitData()
            this.lastWeekWorkingHours = [{
              alearyFillButUnStatic: 'yes',
              isClick: true,
              nowDate: moment(this.model.vestingDay).format('MMMDD日'), //当前日期
              nowWeek: moment(this.model.vestingDay).format('dddd') //当前星期
            }]
            this.mostImportantParams.workId = this.model.id
            // 穿透的时候需要传dataId，值是主表id
            this.mostImportantParams.dataId = this.model.id
            this.loadData()
            // 查询流程历史记录
            this.historyTrackDataSource = await this.getHistoryTrack()
            break
          case 'viewLastWeek':
            // 操作大部分同补填今日
            this.controlLoadData = true
            this.initStatus.formDataParams = this.formDataParams
            await this.setInitData()
            this.lastWeekWorkingHours = [{
              ...this.model,
              isClick: true,
              nowDate: moment(this.model.vestingDay).format('MMMDD日'), //当前日期
              nowWeek: moment(this.model.vestingDay).format('dddd') //当前星期
            }]
            // setInitData里面会将主表内容存入model中，所以直接取model里需要的数据即可
            this.mostImportantParams.workId = this.model.id
            // 手动调用loadData,因为此时将参数设置好了
            this.loadData()
            break
          case 'viewThisWeek':
            // 操作大部分同补填今日
            this.controlLoadData = true
            this.initStatus.formDataParams = this.formDataParams
            await this.setInitData()
            this.lastWeekWorkingHours = [{
              alearyFillButUnStatic: 'yes',
              isClick: true,
              nowDate: moment(this.model.vestingDay).format('MMMDD日'), //当前日期
              nowWeek: moment(this.model.vestingDay).format('dddd') //当前星期
            }]
            // setInitData里面会将主表内容存入model中，所以直接取model里需要的数据即可
            this.mostImportantParams.workId = this.model.id
            // 手动调用loadData,因为此时将参数设置好了
            this.loadData()
            break
          case 'revokeAdd':
            // 调用接口时需要特殊传参，接口同fillLastWeek
            this.controlLoadData = true
            this.initStatus.canEdit = true
            this.initStatus.formDataParams = {
              fillInType: 'fill_in',
            }
            await this.setInitData()
            this.lastWeekWorkingHours = [{
              alearyFillButUnStatic: 'yes',
              isClick: true,
              nowDate: moment(this.model.vestingDay).format('MMMDD日'), //当前日期
              nowWeek: moment(this.model.vestingDay).format('dddd') //当前星期
            }]
            this.mostImportantParams.workId = this.model.id
            this.loadData()
            break
          case 'fillLastWeek':
            this.loading = false
            this.dataSource = []
            await this.setInitData()
            this.controlLoadData = true
            // 可编辑
            this.initStatus.canEdit = true
            this.initStatus.formDataParams = {
              fillInType: 'miss',
            }
            await this.hisWorkingHoursMethod()
            // setInitData里面会将主表内容存入model中，所以直接取model里需要的数据即可
            // this.mostImportantParams.workId = this.model.id
            // 手动调用loadData,因为此时将参数设置好了
            // await this.loadData()
            // this.dataSource.forEach((item) => {
            //   item.fillHours = 0.0
            // })
            break
          default:
            break
        }
      },
      immediate: true,
    },
  },
  computed: {
    // 计算所输入的工时的总和
    sum() {
      let _sum = new Decimal(0)
      if (this.dataSource.length > 0) {
        return this.dataSource.reduce((pre, cur) => {
          pre = new Decimal(pre)
          cur = Number(cur.fillHours) ? new Decimal(cur.fillHours) : new Decimal(0)
          return pre.add(cur)
        }, _sum)
      }
      return new Decimal(0)
    },
    remain() {
      // 保证剩余可填小时不为负数。
      return Math.max(new Decimal(this.total).minus(new Decimal(this.sum)), 0)
    },
  },
  methods: {
    ...mapGetters(['userInfo']),
    // 工时填报-补填查询日表
    async hisWorkingHoursMethod() {
      let res = await getAction(this.url.queryHisWorkingHours)
      if (res.success) {
        /* fillInStatus：yes:已填报，no:未填报
         */
        this.lastWeekWorkingHours = res.result.map(r=>{
          delete r.billNo
          delete r.fillInTime
          return {
            ...r,
            billNo: this.model.billNo,
            fillInTime: this.model.fillInTime,
            isClick: this.nowClickParams.id === r.id ? true : false,
            nowDate: moment(r.vestingDay).format('MMMDD日'), //当前日期
            nowWeek: moment(r.vestingDay).format('dddd') //当前星期
          }
        })
        this.model.handlerDeptId = this.lastWeekWorkingHours[0].handlerDeptId
        this.model.fillInUser = this.lastWeekWorkingHours[0].fillInUser
        /* 首次进来未点击,赋值给第一个 */
        if(JSON.stringify(this.nowClickParams) === '{}'){
          this.clickWorkingHours(this.lastWeekWorkingHours[0])
        }

      }else{
        this.initStatus.canEdit = false 
        this.initStatus.showHistoryTrack = false
        this.$message.error(res.message)
      }
    },
    // 点击切换工时
    clickWorkingHours(item){
      if(this.status=='add' || this.status=='viewThisWeek'){
        return
      }
      this.nowClickParams = {...item}
      this.lastWeekWorkingHours.forEach(it=>{
        if(item.id==it.id){
          item.isClick = true
        }else{
          it.isClick = false
        }
      })
      this.mostImportantParams.workId = item.id
      this.total = 8 
      this.loadData(1)
    },
    /* 补填保存当前数据 */
    saveTo(){
      /* 判断是否符合条件 */
      if(this.judgeCanSubmit(this.nowClickParams.userType)){
        let params = {
          ...this.nowClickParams,
          workingHoursDetailedList: this.dataSource
        }
        delete params.fillInStatus
        params.alearyFillButUnStatic = 'yes'
        
        putAction(this.url.submitData, params).then((res) => {
          if (res.success) {
            this.$message.success('保存成功')
            this.hisWorkingHoursMethod()
          } else {
            this.$message.error(res.message)
          }
        })
      }
    },
    // 设置新增的时候一些数据的初始化
    async setInitData() {
      // 如果是add或者是revokeAdd，则传参数fill_in,去获取单据编号
      let params = {url:'/api/erp/hours/workmain/erpWorkingHours/getBillNo',prefix: 'GSTB', subSystemCode: '05'}
      if(this.status === 'add'||this.status === 'revokeAdd'){
        params.type = 'fill_in'
        const _res = await generatedFormNumber(params)
        _res && this.$set(this.model, 'billNo', _res)
      }else if(this.status === 'fillLastWeek'){
        params.type = 'miss'
        const _res = await generatedFormNumber(params)
        _res && this.$set(this.model, 'billNo', _res)
      }
      const _model = await this.getFormData()
      this.model = {..._model,...this.model}
      if (this.status === 'add' || this.status === 'revokeAdd' || this.status === 'fillLastWeek') {
        this.$set(this.model, 'fillInTime', moment().format('YYYY-MM-DD HH:mm:ss'))
      }
      this.workingHours = [this.model.fillInStartTime, this.model.fillInEndTime]
    },

    // 穿透时候的主表查询改变了
    async setPierceInitData() {
      this.initStatus.formDataParams.id = this.pierceBillNo
      this.model = await this.getFormData()
      this.workingHours = [this.model.fillInStartTime, this.model.fillInEndTime]
    },
    // 提交数据，需要先校验是否能提交
    submitData() {
      if (this.status === 'add') {
        if (this.judgeCanSubmit()) {
          // 填报今日的提交
          this.$set(this.model, 'workingHoursDetailedList', this.dataSource)
          this.confirmLoading = true
          postAction(this.url.submitData, this.model).then((res) => {
            if (res.success) {
              this.$message.success('提交成功')
              this.$emit('submitSuccess')
            } else {
              this.$message.error(res.message)
            }
          }).finally(() => {
            this.confirmLoading = false
            this.$emit('canClickSubmit')
          })

        } else {
          this.$emit('canClickSubmit')
        }

      }else if (this.status === 'fillLastWeek') {
        /* 历史总的补填提交 */
        let statusList = this.lastWeekWorkingHours.map(r=>r.alearyFillButUnStatic)
        /* 判断是否有未填的 */
        if(statusList.includes('no')){
          let msgDate = this.lastWeekWorkingHours.filter(r=>r.alearyFillButUnStatic==='no').map(r=>r.vestingDay)
          this.$message.error(`请完成${String(msgDate)}工时补填`)
          this.$emit('canClickSubmit')
          return
        }
        this.confirmLoading = true
        let ids = this.lastWeekWorkingHours.map(r=>r.id)
        let params = {
          workIds: String(ids)
        }
        // 补填的提交
        putAction(this.url.allSubmitUrl, params).then((res) => {
          if (res.success) {
            this.$emit('submitSuccess')
          } else {
            this.$message.error(res.message)
          }
        }).finally(() => {
          this.confirmLoading = false
          this.$emit('canClickSubmit')
        })

      }
      
    },
    
    // 校验是否符合提交要求
    judgeCanSubmit(type) {
      const _sum = new Decimal(this.sum)
      const _total = new Decimal(this.total)
      if (_sum.equals(_total)) {
        return true
      } else if (_sum.lessThan(_total)) {
        /* 有type则表示补填的保存判断 */
        if(type){
          if(type === 'white'){
            this.$message.error('白名单人员不用填写!')
            return false
          }

          if(type === 'coordinator'){
            this.$message.error(`当前工时之和必须等于${this.total}小时才可提交`)
            return false
          }

          if(type === 'product_coordinator' || type === 'r_and_d_coordinator'){
            /* 生产/研发统筹人员，工时可小于或等于8小时 */
            return true
          }

        }else{
          if (this.userType === 'coordinator') {
            this.$message.warning(`当前工时之和必须等于${this.total}小时才可提交`)
            return false
          }
          if(this.userType === 'product_coordinator' || this.userType === 'r_and_d_coordinator'){
            /* 生产/研发统筹人员，工时可小于或等于8小时 */
            return true
          }
        }
        
        this.$message.warning(`当前工时之和小于${this.total}小时，不可提交`)
        return false
      } else {
        this.$message.warning(`当前工时之和大于${this.total}小时，不可提交`)
        return false
      }
    },
    // 重置initStatus数据状态为data里面的初始状态，即都为false
    resetInitStatus() {
      this.nowClickParams = {}
      this.lastWeekWorkingHours = []
      this.initStatus = this.$options.data().initStatus
      this.mostImportantParams = this.$options.data().mostImportantParams
      this.model = this.$options.data().model
      this.dataSource = this.$options.data().dataSource
    },
    // 查询主表接口
    async getFormData() {
      return getAction(this.url.getFormData, this.initStatus.formDataParams).then((res) => {
        if (res.success) {
          const _res = this.status === 'add' ? res.result : res.result.records[0]
          return _res
        }
      })
    },
    // 查询流程历史记录
    async getHistoryTrack() {
      return getAction(this.url.getHistoryTrack, this.mostImportantParams).then((res) => {
        if (res.success) {
          return res.result.records
        }
      })
    },
    // 点击项目名称穿透
    clickProjectName(record) {
      getAction(this.url.queryProjectById, { id: record.projectId }).then((res) => {
        if (res.success) {
          const model = res.result
          this.$refs.viewProjectDetail.getDetail(model)
          this.$refs.viewProjectDetail.title = '项目一览表'
        }
      })
    },
    // 设置fillHours的方法,用来解决清空后直接点击提交的bug
    changeFillHours(record){
      if(!record.fillHours){
        record.fillHours = 0.0
      }
    }
  },
}
</script>
<style scoped lang="less">
.ipt-task-time-header-right {
  font-weight: bold;
  color: rgb(217, 0, 27);
  margin-left: 20px;
}
.date-area {
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  width: 100px;
  height: 80px;
  margin-left: 10px;
  cursor: pointer;
  position: relative;
  background: #EEEEEE;
  color: #000000;
  .date {
    font-size: 22px;
  }
  .week {
    font-size: 16px;
  }
  .left-icon {
    width: 30px;
    height: 30px;
    position: absolute;
    top: -10px;
    left: -10px;
  }
}
// .date-area:hover{
//   background: #DDDDDD;
// }
.fl-right{
  float: right;
  margin-bottom: 30px;
}
.bg1 {
  background: #14e6b4;
}
</style>
